
public class Spell extends GameObject implements Updateable
{
    static final int DAMAGE_LEVEL_1 = 10;
    static final int DAMAGE_LEVEL_2 = 20;
    static final int DAMAGE_LEVEL_3 = 50;
    static final int DAMAGE_LEVEL_EPIC = 999;
    
    static final int MANACOST_LEVEL_1 = 1;
    static final int MANACOST_LEVEL_2 = 20;
    static final int MANACOST_LEVEL_3 = 50;
    static final int MANACOST_LEVEL_EPIC = 1;
    
    static final int DISTANCE_LEVEL_1 = 5;
    
    //double speed;
    Direction direction;
    int damage;
    int distanceMax;
    int distanceTraveled = 0;
    Element element;    
    boolean playerSpell;
    int manaCost;
    double modifier;
    
    Spell
    (
        //Player caster, 
        boolean playerSpell,
        int x, 
        int y, 
        Direction direction,
        double modifier,
        int damage,
        int manaCost,
        int distanceMax,
        Element element,
        String filePath
    )
    {
        //this.caster = caster;
        this.x = x;
        this.y = y;
        this.direction = direction;     
        this.damage = damage;
        this.modifier = modifier;
        this.manaCost = manaCost;
        this.distanceMax = distanceMax;
        this.distanceTraveled = 0;
        this.element = element;
        this.filePath = filePath;
        this.playerSpell = playerSpell;
    }

    public void move()
    {
        if(distanceTraveled > 5)
        {
            map[this.x][this.y].gameObject = null;
            map[this.x][this.y].update();
            this.x = 20;
            this.y = 20;
            
            return;
        }       
        
        Direction d = this.direction;
        int nextX = this.x;
        int nextY = this.y;     
        
        if(d == Direction.Down){nextY++;}
        else if(d == Direction.Up){nextY--;}
        else if(d == Direction.Left){nextX--;}
        else if(d == Direction.Right){nextX++;}
                
        for(GameObject go: GameObject.gameObjects)
        {
            int i = GameObject.gameObjects.indexOf(this);
            if(!(i == GameObject.gameObjects.indexOf(go)))
            {
                if(nextX == go.x && nextY == go.y)
                {
                    //set it outside our bounds, and it will be deleted on next update
                    nextX=20;
                    nextY=20;
                    //check for spell damage
                    if(go instanceof Player)
                    {
                        if(go instanceof Mob)
                        {
                            if(this.playerSpell)
                            {
                                Mob m = (Mob)go;
                                double z = this.damage*Element.damageModifier(this.element, m.elemType);                            
                                m.takeDamage((int)z);
                            }
                        }
                        else //Player
                        {
                            if(!this.playerSpell)
                            {
                                Player p = (Player)go;
                                double z = 
                                    this.damage*Element.damageModifier(this.element, p.activeSpell.element);                            
                                p.takeDamage((int)z);
                            }
                        }
                    }
                }
            }
        }
        
        //do the actual moving
        if(this.x != nextX || this.y!=nextY)
        {
                if(this.x <13 && this.y<13)
                {
                    if (distanceTraveled != 0)
                    {
                        map[this.x][this.y].gameObject = null;
                        map[this.x][this.y].update();   
                    }
                    
                }
                if(nextX <13 && nextY<13)
                {
                    map[nextX][nextY].gameObject = this;
                    map[nextX][nextY].update();
                }
        }
        
        this.x = nextX;
        this.y = nextY;
        this.distanceTraveled++;
    }
    
    public void update()
    {
        this.move();
    }
    
}
